﻿using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Security;
using System.Threading;
using System.Web.ClientServices;
using System.Web.ClientServices.Providers;
using System.Web.Security;
using System.Windows.Forms;
using RedRiver.Framework.AppFramework.Properties;
using RedRiver.Framework.AppFramework.UserInfoService;
using RedRiver.Framework.XtraCommon.FormHelper;
using RedRiver.Framework.XtraCommon.Models;
using RedRiver.Framework.XtraCommon.Templates;
using RedRiver.Framework.XtraCommon.UserAuthentication;

namespace RedRiver.Framework.AppFramework{
    internal static class Program{
        private static string _lastExMessage;

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        public static void Main(){
            try{
                string appName = Settings.Default.ApplicationName;
                UserContext.GlobalConst.ApplicationName = appName;
                Trace.Listeners.Add(new TextWriterTraceListener(appName + ".log"));
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                XtraMessageForm.ShowMessage("正在启动 " + appName);
                CheckDeployUpdate.UpdateApplication();
                Application.ThreadException += ApplicationThreadException;
                Application.ApplicationExit += ApplicationApplicationExit;
                while (AspNetLogin()){
                    try{
                        //InitProfileSettings();
                        //AutoLoadedClasses();
                        CheckNavBarInfo(NavBarInfo.DefaultInfoFilePath, string.Empty);
                        var form = new MainFrameForm{Text = appName, WindowState = FormWindowState.Maximized};
                        Application.Run(form);
                        break;
                    } catch (SecurityException securityException){
                        if (
                            MessageBox.Show(@"用户未能通过安全权限验证,是否重新登陆?
" + securityException.Message, Resources.MsgTitle,
                                            MessageBoxButtons.YesNo, MessageBoxIcon.Question) !=
                            DialogResult.Yes){
                            return;
                        }
                    }
                }
            }catch(Exception ex){
                MessageBox.Show(ex.ToString(),@"异常信息", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }

        private static void InitProfileSettings(){
            XtraMessageForm.ShowMessage("正在初始化用户设置...");
            ClientSettingsProvider.ServiceUri = UserContext.GlobalConst.BaseUrl + "Profile_JSON_AppService.axd";
        }

        private static bool AspNetLogin(){
            if (Settings.Default.NotUserLogin){
                return true;
            }
            try{
                UserContext.GlobalConst.BaseUrl = Settings.Default.ServerURL;
                if (Membership.Provider is ClientFormsAuthenticationMembershipProvider){
                    var provider = (ClientFormsAuthenticationMembershipProvider) Membership.Provider;
                    provider.UserValidated += ClientFormsUserValidated;
                    Application.ApplicationExit += ApplicationApplicationExit;
                }
                return Membership.ValidateUser(string.Empty, string.Empty);
            } catch (WebException ex){
                ShowWebException(ex);
                return false;
            }
        }

        private static void ClientFormsUserValidated(object sender, UserValidatedEventArgs e){
            if (string.IsNullOrEmpty(e.UserName)){
                return;
            }
            QueryUserInfo();
            InitProfileSettings();
            XtraMessageForm.Hiden();
        }

        private static void QueryUserInfo(){
            try{
                XtraMessageForm.ShowMessage("正在获取用户信息...");
                if (! string.IsNullOrEmpty(UserContext.GlobalConst.BaseUrl)){
                    var service = new UserInfoService.UserInfoService();
                    service.Url = UserContext.GlobalConst.BaseUrl + "Services/UserInfoService.asmx";
                    if (Thread.CurrentPrincipal.Identity is ClientFormsIdentity){
                        var identity = (ClientFormsIdentity) Thread.CurrentPrincipal.Identity;
                        service.CookieContainer = identity.AuthenticationCookies;
                    }
                    Employee user = service.GetCurrentUser();
                    UserContext.GlobalConst.BeginEdit();
                    UserContext.GlobalConst.UserName = user.UserName;
                    UserContext.GlobalConst.UserFullName = user.FullName;
                    UserContext.GlobalConst.UserDepCode =
                        user.DepartmentReference.EntityKey.EntityKeyValues[0].Value.ToString();
                    UserContext.GlobalConst.UserDepName = user.DepartmentName;
                    UserContext.GlobalConst.EmployeeCode = user.EmployeeCode;
                    UserContext.GlobalConst.EndEdit();
                    service.Dispose();
                } else{
                    throw new NullReferenceException("BaseUrl Is Null");
                }
            } catch (Exception ex){
                Trace.WriteLine(ex);
            }
        }

        private static void ShowWebException(WebException ex){
            var form = new WebPageForm();
            if (ex.Response != null){
                form.DocumentStream = ex.Response.GetResponseStream(); //.Message;    
            } else{
                form.DocumentText = ex.Message;
            }

            form.FormTitle = ex.Message;
            form.ShowDialog();
            Trace.WriteLine(ex);
        }

        private static void ApplicationApplicationExit(object sender, EventArgs e){
            Trace.Refresh();
            Trace.Close();
        }

        private static void ApplicationThreadException(object sender, ThreadExceptionEventArgs e){
            string msg = e.Exception.Message;
            if (!msg.Equals(_lastExMessage)){
                Trace.WriteLine(e.Exception.ToString(), sender.ToString());
                MessageBox.Show(e.Exception.Message, Resources.MsgTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            } else{
                XtraMessageForm.ShowException(e.Exception.Message, e.Exception, 3);
            }
            _lastExMessage = e.Exception.Message;
        }

        private static void CheckNavBarInfo(string filePath, string option){
            if ((!File.Exists(filePath)) ||
                (option.EndsWith("REGENNAVBAR",StringComparison.CurrentCultureIgnoreCase))){
                var builder = new NavBarInfoBuilder(filePath);
                builder.ShowDialog();
                if (builder.IsDataChanged){} else{
                    throw new FileLoadException("配置文件" + filePath + "不存在,需要重新生成");
                }
            }
        }

        #region OldCode

        /*
        private static void AutoLoadedClasses(){
            foreach (string typeName in Settings.Default.AutoLoadClasses){
                Type loadType = GetItemType(typeName);
                if (loadType != null){
                    try{
                        ///创建类型实例
                        Activator.CreateInstance(loadType, true);
                        Trace.WriteLine("加载自动加载 类型 " + typeName);
                    } catch (Exception ex){
                        Trace.WriteLine("加载自动加载 类型 " + typeName + "失败," + ex.Message);
                    }
                }
            }
        } /// <summary>
        /// 获得导航项目类型
        /// </summary>
        /// <returns></returns>
        private static Type GetItemType(string typeName){
            Type itemType = SystemInfo.GetTypeFromString(typeName, false, false);
            if (itemType != null){
                return itemType;
            }
            //根据 类型全称 查找程序集文件并尝试加载
            string[] assemblyParts = typeName.Split('.');
            string assemblyPattern = assemblyParts.Length > 2
                                         ? string.Join(".", assemblyParts, 0, 2)
                                         : string.Join(".", assemblyParts);
            string[] assemblyFiles = Directory.GetFiles(Application.StartupPath, assemblyPattern + "*.dll");
            Assembly assembly;
            foreach (string assemblyFile in assemblyFiles){
                try{
                    assembly = Assembly.LoadFrom(assemblyFile);
                    itemType = assembly.GetType(typeName, false, true);
                    if (itemType != null){
                        return itemType;
                    }
                } catch (Exception ex){
                    Trace.WriteLine("加载 程序集 " + assemblyFile + " 失败," + ex.Message);
                }
            }
            return null;
        }
        */

        #endregion OldCode
    }
}